package com.freejy.ecommunity.service;

import com.freejy.ecommunity.common.Constants;
import com.freejy.ecommunity.common.Global;
import com.freejy.ecommunity.common.Token;
import com.freejy.ecommunity.model.Account;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class TokenProvider {
	
	private final Logger log = LoggerFactory.getLogger(TokenProvider.class);
	
    private static String secretKey;
    private static int tokenValidity;
    
    private static TokenProvider instance = new TokenProvider();

    static {
    	secretKey = Global.getConfig("auth.secret", "");
    	tokenValidity = Integer.valueOf(Global.getConfig("token.expires", Constants.TOKEN_EXPIRES_DEFAULT + ""));
    }
    
    private TokenProvider(){}
    
    public static TokenProvider getInstance(){
    	return instance;
    }
    
    /**
     * 生成token
     * @param account
     * @return
     */
    public Token createToken(Account account) {
        long expires = System.currentTimeMillis() + 1000L * tokenValidity * 3600 * 24; // 用天来定义生命期限
        String token = computeSignature(account, expires);
        return new Token(account.getId(), account.getUuid(), account.getNickname(), account.getAvatar(), account.getGender(), token, expires);
    }

    /**
     * token 生成算法
     * @param account
     * @param expires
     * @return
     */
    private String computeSignature(Account account, long expires) {
        StringBuilder signatureBuilder = new StringBuilder();
        signatureBuilder.append(account.getId()).append(":");
        signatureBuilder.append(expires).append(":");
        signatureBuilder.append(account.getUuid()).append(":");
        signatureBuilder.append(secretKey);

        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("No MD5 algorithm available!");
        }
        return new String(Hex.encodeHex(digest.digest(signatureBuilder.toString().getBytes())));
    }

    /**
     * token 校验
     * @param token
     * @param account
     * @return
     */
    public boolean validateToken(Token token, Account account) {
    	log.debug("validateToken exp={}", token.getToken());
        long expires = token.getExpires();
        String signature = token.getToken();
        String signatureToMatch = computeSignature(account, expires);
        return expires >= System.currentTimeMillis() && signature.equals(signatureToMatch);
    }

    /**
     * token 时效校验
     * @param token
     * @return
     */
    public boolean expires(Token token) {
        log.debug("token={}", token.getToken());
        long expires = token.getExpires();
        return expires < System.currentTimeMillis() ;
    }
    
}
